import { AddMenuParam, EditMenuParam, GetMenuParams, PutMenuStateParams, UserListReturnType } from "@Tea/model"
import { TokenObj } from "../dao/Token"
import { MenuRepository } from "../repo/MenuRepository"
import { MenuItemType, UserMenuRepository } from "../repo/UserMenuRepository"

export type SystemRouter = MenuItemType & {
  children : SystemRouter[] | undefined
}

export class MenuContext { 
  private static inst: MenuContext
  private userMenuRepo: UserMenuRepository = UserMenuRepository.getInstance()
  private MenuRepo: MenuRepository = MenuRepository.getInstance()

  public static getInstance() {
    if (!MenuContext.inst) {
      MenuContext.inst = new MenuContext()
    }

    return  MenuContext.inst
  }

  // 处理menu
  protected handleMenu(menu:MenuItemType[]) {
    // 已经存入的 数据
    const joinedStack = new Map<SystemRouter["menuId"], SystemRouter>()
    let result = {} as SystemRouter

    while (menu.length !== 0) {
      const m = menu.shift() as any as SystemRouter
      m.children = undefined
      // 如果没有 父id 说明是根路由
      if (!m.pMenuId) {
        m.children = []
        result = m
      }

      // 找到父路由的话就将它推入

      const pRouter = joinedStack.get(m.pMenuId)
      
      if (pRouter) {
        // 父可能没有 children 这个属性
        if (!pRouter.children) {
          pRouter.children = []
        }
        pRouter.children.push(m)
      }

      // 不管有没有匹配到父都将它推入
      joinedStack.set(m.menuId, m)
    }
    
    return result
  }

  async getUserMenu(userId: TokenObj["userId"]) {
    
    const menu = (await this.userMenuRepo.getUserMenu(userId))[0]

    return this.handleMenu(menu)
  }

  // 获取所有系统菜单
  async getSystemMenu(params: GetMenuParams) {
    
   const menu = (await this.MenuRepo.getSystemMenu(params))[0]
    
   return menu
  }

  // 添加菜单
  addMenu(params: AddMenuParam, hander: TokenObj["userId"]) {
    return this.MenuRepo.addMenu(params,hander)
  }

  // 编辑菜单
  editMenu(params: EditMenuParam, hander: TokenObj["userId"]) {
    return this.MenuRepo.editMenu(params,hander)
  }

  // 删除菜单
  deleteMenu(params: MenuItemType["menuId"][]) {
    return this.MenuRepo.deleteMenu(params)
  }

  // 改变状态
  putMenuState(params: PutMenuStateParams, hander: TokenObj["userId"]) {
    return this.MenuRepo.putMenuState(params,hander)
  }

  // 通过 userid 获取 成员的菜单id
  getUserMenuIdById(userId: UserListReturnType["userId"]) {
    return this.userMenuRepo.getUserMenuIdById(userId)
  }
}